﻿/*
 * Copyright(C) 2012,ajayumi 保留所有权利。( All rights reserved. )
 * 
 * 文件名称：AjFormsPrincipal.cs
 * 摘    要：
 * 当前版本：1.0
 * 作    者：黄乙冬 (ajayumi)
 * 创建日期：2012年5月31日星期四
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Principal;
using System.Web.Security;
using System.Web;
using System.Web.Script.Serialization;

namespace ajayumi.Platform.Web.Security
{
    public class AjFormsPrincipal<TUserData> : IPrincipal
        where TUserData : class, new()
    {
        private IIdentity m_Identity = null;

        public IIdentity Identity
        {
            get { return this.m_Identity; }
        }

        public TUserData UserData { get; private set; }

        public AjFormsPrincipal(FormsAuthenticationTicket ticket, TUserData userData)
        {
            if (ticket == null)
            { throw new ArgumentNullException("ticket"); }
            if (userData == null)
            { throw new ArgumentNullException("userData"); }

            this.m_Identity = new FormsIdentity(ticket);
            this.UserData = userData;
        }

        public bool IsInRole(string role)
        {
            // 把判断用户组的操作留给UserData去实现。
            IPrincipal principal = this.UserData as IPrincipal;
            if (principal == null)
            { throw new NotImplementedException(); }
            else
            { return principal.IsInRole(role); }
        }


        /// <summary>
        /// 执行用户登录操作
        /// </summary>
        /// <param name="loginName">登录名</param>
        /// <param name="userData">与登录名相关的用户信息</param>
        /// <param name="expiration">登录Cookie的过期时间，单位：分钟。</param>
        public static void SignIn(string loginName, TUserData userData, int expiration)
        {
            if (string.IsNullOrEmpty(loginName))
            { throw new ArgumentNullException("loginName"); }
            if (userData == null)
            { throw new ArgumentNullException("userData"); }

            // 1. 把需要保存的用户数据转成一个字符串。
            string data = null;
            if (userData != null)
            { data = (new JavaScriptSerializer()).Serialize(userData); }


            // 2. 创建一个FormsAuthenticationTicket，它包含登录名以及额外的用户数据。
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, loginName, DateTime.Now, DateTime.Now.AddDays(1), true, data);


            // 3. 加密Ticket，变成一个加密的字符串。
            string cookieValue = FormsAuthentication.Encrypt(ticket);


            // 4. 根据加密结果创建登录Cookie
            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue);
            cookie.HttpOnly = true;
            cookie.Secure = FormsAuthentication.RequireSSL;
            cookie.Domain = FormsAuthentication.CookieDomain;
            cookie.Path = FormsAuthentication.FormsCookiePath;
            if (expiration > 0)
            { cookie.Expires = DateTime.Now.AddMinutes(expiration); }

            HttpContext context = HttpContext.Current;
            if (context == null)
            { throw new InvalidOperationException(); }

            // 5. 写登录Cookie
            context.Response.Cookies.Remove(cookie.Name);
            context.Response.Cookies.Add(cookie);
        }
    }
}
